import { ref } from "vue";
import { uploads } from "@/api/upload";
import { downloadFile } from "@/utils/file";
import { ElMessage } from "element-plus";
interface FileInfos {
  url: string;
}
export interface BatchFileFace {
  name: string;
  file?: File;
  fileInfo?: FileInfos; // 成功的信息
  errorInfo?: any;
  isUpload: 1 | 2 | 0; // 是否上传成功 0 等待上传 1 上传成功  2上传失败
  progress: number; // 上传进度
}
// 选择文件 返回 File,后续可扩展类型
export const useFileUpload = () => {
  const files = ref<File | null>(null);
  const isFile = ref<boolean>(false);
  const batchFile = ref<BatchFileFace[]>([]);
  const acceptType: Record<string, string> = {
    excel: ".xls,.xlsx",
    image: "image/*",
  };
  /**
   * 上传文件
   * @param file 文件
   * @param callback  上传进度回调方法
   * @returns
   */
  const uploadFile = (file: File, callback?: Function): Promise<FileInfos> => {
    return new Promise((resolve, reject) => {
      const obj = {
        file,
      };
      uploads(obj, callback)
        .then((res) => {
          resolve(res.data);
        })
        .catch((err) => {
          reject();
        });
    });
  };
  interface Option {
    accept: string;
  }
  /**
   *  选择文件
   * @param option  {accept:'文件类型'}
   * @returns
   */
  const handleUpload = (option?: Option): Promise<File> => {
    return new Promise((resolve, reject) => {
      let accept =  option?.accept;
   
      createInput({ accept })
        .then((res) => {
          files.value = res[0] as File;
          resolve(files.value);
        })
        .catch((err) => {
          reject(err);
        });
    });
  };
  const createImage=()=>{
    const getImageInfo = (file: File): Promise<any> => {
      return new Promise((resolve, reject) => {
        let _URL = window.URL || window.webkitURL;
        let image = new Image();
        image.src = _URL.createObjectURL(file);
        image.onload = function () {
          resolve({ width: image.width, height: image.height });
        };
      });
    };
  }

  /**
   * 选择多个文件
   * @returns
   */
  const handleBatchFile = () => {
    return new Promise((resolve, reject) => {
      createInput({ accept: acceptType.image, multiple: true })
        .then((res) => {
          console.log(res);
          addFile(res);
          resolve(batchFile.value);
        })
        .catch((err) => {
          reject(err);
        });
    });
  };
  const handleCloseFile = (index: number) => {
    if (isFile.value) return ElMessage.error("正在上传中，请勿进行删除操作");
    batchFile.value.splice(index, 1);
  };

  interface fileInput {
    accept?: string;
    multiple?: boolean;
  }
  const addFile = (files: File[]) => {
    if (!batchFile.value || batchFile.value.length == 0) {
      batchFile.value = [];
    }
    Array.prototype.forEach.call(files, (item) => {
      const { name, size, lastModified, type } = item;
      const fileData = batchFile.value.find(
        (v) => v.file && v.file.name == name
      );
      // 检查文件是否存在,先简单对比下吧
      if (
        fileData &&
        fileData.file &&
        fileData.file.size === size &&
        fileData.file.lastModified === lastModified &&
        fileData.file.type === type
      ) {
        return;
      } else {
        batchFile.value.push({
          name,
          file: item,
          isUpload: 0,
          progress: 0,
          fileInfo: undefined,
        });
      }
    });
  };
  /**
   * 创建input上传框
   * @param data { accept:'文件类型',multiple:booloe是否多选 }
   * @returns
   */
  const createInput = (data: fileInput = {}): Promise<File[]> => {
    const { accept, multiple } = data;
    return new Promise((resolve, reject) => {
      var input: HTMLInputElement = document.createElement("input"); // 创建一个 a 标签
      input.accept = accept || "*";
      input.type = "file";
      input.multiple = multiple ? true : false;
      input.onchange = (e: any) => {
        resolve(e.target.files);
      };
      document.body.appendChild(input);
      input.click();
      function monitor() {
        document.removeEventListener("mousemove", monitor);
        document.body.removeChild(input);
      }
      document.addEventListener("mousemove", monitor, false);
    });
  };

  /**
   * 批量 并发 上传当前选择的文件列表
   * @param {File[]} list 文件数组
   * @param {Number} size 并发数量
   * @returns
   */
  const walkRequest = (size: number = 3): Promise<BatchFileFace[]> => {
    return new Promise((resolve, reject) => {
      if (batchFile.value.length === 0) {
        resolve([]);
        return;
      }
      size = size > batchFile.value.length ? batchFile.value.length : size;
      isFile.value = true;
      const results: any = [];
      let index = 0; // 下一个请求的下标
      let count = 0; // 判断是否全部请求完成

      const finallyFun = () => {
        count++;
        if (index < batchFile.value.length) {
          qingqiu();
        }
        if (count === batchFile.value.length) {
          isFile.value = false;
          resolve(batchFile.value);
        }
      };

      const qingqiu = async () => {
        const i = index;
        index++;

        if (batchFile.value[i].isUpload === 1) {
          // 初始可能存在数量不够问题，先派发到微任务，等待for 循环结束再处理
          setTimeout(() => {
            finallyFun();
          }, 1);
          return;
        }
        const obj = {
          file: batchFile.value[i].file,
        };
        try {
          const fileInfo = await uploads(obj, (e: any) => {
            batchFile.value[i].progress = Math.floor(e.progress * 100);
          });
          batchFile.value[i].fileInfo = fileInfo.data;
          batchFile.value[i].isUpload = 1;
        } catch (err) {
          batchFile.value[i].errorInfo = err;
          console.log("上传失败");
          batchFile.value[i].isUpload = 2;
        } finally {
          finallyFun();
        }
      };
      for (let i = 0; i < size; i++) {
        console.log(i);
        qingqiu();
      }
    });
  };

  return {
    handleUpload,
    handleBatchFile,
    batchFile,
    files,
    handleCloseFile,
    walkRequest,
    uploadFile,
  };
};
